package com.example.gui.todos.view;

import com.example.gui.todos.controller.TodoController;
import com.example.gui.todos.model.Todo;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class TodoView {
    private final BorderPane root; // 根布局容器（BorderPane）
    private final TextField inputField; // 待办内容输入框
    private final ListView<Todo> todoListView; // 待办列表展示
    private final ObservableList<Todo> todoList; // 动态数据列表（支持UI绑定）

    // 构造方法：初始化视图组件
    public TodoView() {
        // 1. 初始化动态数据列表
        todoList = FXCollections.observableArrayList();

        // 2. 初始化UI核心组件
        inputField = new TextField();
        Button addBtn = new Button("添加");
        Button deleteBtn = new Button("删除选中");
        Button clearBtn = new Button("清空所有");
        todoListView = new ListView<>(todoList);

        // 3. 配置组件属性
        inputField.setPromptText("输入待办事项内容..."); // 输入框提示文本
        deleteBtn.getStyleClass().add("delete"); // 为删除按钮添加CSS样式类
        todoListView.setCellFactory(param -> new TodoListCell()); // 自定义列表项样式

        // 4. 构建布局结构
        BorderPane root = new BorderPane();
        HBox inputBox = new HBox(10, inputField, addBtn); // 输入区域（水平布局）
        HBox buttonBox = new HBox(10, deleteBtn, clearBtn); // 按钮组（水平布局）
        VBox centerBox = new VBox(10, todoListView, buttonBox); // 中部区域（垂直布局）

        // 5. 配置布局边距与约束
        inputBox.setPadding(new Insets(10));
        centerBox.setPadding(new Insets(0, 10, 10, 10));
        root.setTop(inputBox);
        root.setCenter(centerBox);

        // 6. 绑定控制器与事件
        TodoController controller = new TodoController(this);
        addBtn.setOnAction(e -> controller.handleAddTodo());
        deleteBtn.setOnAction(e -> controller.handleDeleteSelected());
        clearBtn.setOnAction(e -> controller.handleClearAll());

        // 7. 初始化数据加载与保存监听
        this.root = root;
        loadTodosFromFile(); // 启动时加载本地数据
        setupCloseListener(); // 窗口关闭时保存数据
    }

    // 自定义列表项（含复选框与动态样式）
    private class TodoListCell extends ListCell<Todo> {
        private final CheckBox checkBox = new CheckBox();

        @Override
        protected void updateItem(Todo todo, boolean empty) {
            super.updateItem(todo, empty);
            if (empty || todo == null) {
                setGraphic(null);
            } else {
                // 绑定复选框状态与待办数据
                checkBox.textProperty().bind(todo.contentProperty());
                checkBox.selectedProperty().bindBidirectional(todo.isCompletedProperty());

                // 动态样式：已完成项显示删除线
                checkBox.styleProperty().bind(Bindings.when(todo.isCompletedProperty())
                        .then("-fx-text-fill: gray; -fx-strikethrough: true;")
                        .otherwise("-fx-text-fill: black;"));
                setGraphic(checkBox);
            }
        }
    }

    // 窗口关闭事件监听（保存数据）
    private void setupCloseListener() {
        root.sceneProperty().addListener((obs, oldScene, newScene) -> {
            if (newScene != null) {
                newScene.windowProperty().addListener((obsWindow, oldWindow, newWindow) -> {
                    if (newWindow != null) {
                        newWindow.setOnCloseRequest(e -> saveTodosToFile());
                    }
                });
            }
        });
    }

    // 从本地文件加载待办数据
    private void loadTodosFromFile() {
        File file = new File("todos.dat");
        if (!file.exists()) return;

        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
            List<Todo> savedTodos = (List<Todo>) ois.readObject();
            todoList.addAll(savedTodos);
        } catch (Exception e) {
            showAlert("加载失败", "无法读取本地数据：" + e.getMessage());
        }
    }

    // 将待办数据保存到本地文件
    private void saveTodosToFile() {
        List<Todo> todosToSave = new ArrayList<>(todoList);
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("todos.dat"))) {
            oos.writeObject(todosToSave);
        } catch (IOException e) {
            showAlert("保存失败", "无法写入本地数据：" + e.getMessage());
        }
    }

    // 错误提示对话框
    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle(title);
        alert.setContentText(message);
        alert.showAndWait();
    }

    // Getter方法（供控制器访问视图组件）
    public BorderPane getRoot() { return root; }
    public TextField getInputField() { return inputField; }
    public ObservableList<Todo> getTodoList() { return todoList; }
    public ListView<Todo> getTodoListView() { return todoListView; }
}